package net.gz01.wallet.web.controller.admin;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

import net.gz01.wallet.web.service.ReportService;
import org.jxls.common.Context;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;

import lombok.extern.slf4j.Slf4j;
import net.gz01.util.ZODate;
import net.gz01.util.ZOExcel;
import net.gz01.wallet.channel.ChannelFactory;
import net.gz01.wallet.common.Certificate;
import net.gz01.wallet.common.PageRespon;
import net.gz01.wallet.common.ZOSearchCondition;
import net.gz01.wallet.message.QueryReq;
import net.gz01.wallet.message.QueryResp;
import net.gz01.wallet.web.config.SystemConfig;
import net.gz01.wallet.web.config.SystemEnum;
import net.gz01.wallet.web.config.SystemEnum.OrderStatus;
import net.gz01.wallet.web.config.SystemEnum.Resp;
import net.gz01.wallet.web.controller.BaseController;
import net.gz01.wallet.web.model.Dictionary;
import net.gz01.wallet.web.model.TradeOrder;

@Slf4j
public class TradeOrderController extends BaseController {

	public void search() {
		setAttr("bizTypeList", Dictionary.dao.selectBizType());
		setAttr("orderStatusList", Dictionary.dao.selectOrderStatus());
		render("trade/tradeOrderList.html");
	}

	public void listJson() {
		ZOSearchCondition sc = super.getSearchCondition();
		Page<TradeOrder> pageResult = TradeOrder.dao.searchOrder(sc);
		PageRespon pageRespon = new PageRespon(pageResult);
		pageRespon.setTotalInfo(TradeOrder.dao.selectTotalInfo(sc));
		renderJson(pageRespon);
	}

	public void view() {
		TradeOrder item = TradeOrder.dao.findById(getPara("id"));
		File fileList = new File(SystemEnum.FilePath.Trade.getValue() + item.getOrderNo());
		int num = 0;
		if(fileList!=null && fileList.list()!=null){
			num = fileList.list().length;
		}
		setAttr("fileNum", num);
		setAttr("fileList", fileList.list());
		setAttr("order", item);
		render("trade/tradeOrderView.html");
	}

	public void queryOrderStatus() {
		String id = getPara("id");
		TradeOrder tradeOrder = TradeOrder.dao.findById(id);
		if (tradeOrder.getOrderStatus().equals(OrderStatus.InProcess.getValue())) {
			try {
				QueryResp resp = ChannelFactory.get(tradeOrder.getChannelCode()).query(new QueryReq(), tradeOrder);
				if (Resp.Success.getCode().equals(resp.getOriginalRespCode())) {
					tradeOrder.setOrderStatus(OrderStatus.Success.getValue());
					tradeOrder.setPayTime(ZODate.getDateTime());
				}
				if (Resp.Fail.getCode().equals(resp.getOriginalRespCode())) {
					tradeOrder.setOrderStatus(OrderStatus.Fail.getValue());
					tradeOrder.setPayTime(ZODate.getDateTime());
				}
				tradeOrder.update();
				renderSuccess("订单查询成功.");

			} catch (Exception e) {
				log.error("查询异常" + e);
				renderFail("查询异常");
			}
		} else {
			renderSuccess("订单查询成功.");
		}
	}


	public void charts() {
		String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		// select substring(createTime,12,2),count(*),sum(amount) from trade_order group by substring(createTime,12,2) order by substring(createTime,12,2)
		String sql = "select count(*) as count, sum(amount) as total from trade_order where createTime like ?";
		//String sql = "select sum(amount) from trade_order where merchCode=? and createTime like ?";
		List<Record> records = new ArrayList<>();
		DecimalFormat df = new DecimalFormat("00");
		for (int i = 0; i < 24; i++) {
			Record record = Db.findFirst(sql, date +" "+df.format(i)+"%");
			if (record.getInt("total") == null) {
				record.set("total", 0);
			}else {
				record.set("total", record.getInt("total")/100);			// 分转元，图表展示不需要百分百精确
			}
			records.add(record);
		}
		renderJson(records);
	}

	/** 展示电子回单图形 */
	public void certificate() throws Exception {
		File file = new File(SystemConfig.config.get("file_center_path") + "certificate/" + getPara("id") + ".jpg");
		if (file.exists()) {
			renderFile(file);
		} else {
			TradeOrder order = TradeOrder.dao.findById(getPara("id"));
			BufferedImage image = Certificate.createImage(order);
			FileOutputStream fos = new FileOutputStream(file);
			ImageIO.write(image, "jpeg", fos);
			fos.close();
			renderFile(file);
		}
	}


	public void report() throws Exception {
		List<Dictionary> payTypeList = Dictionary.dao.selectBizType();
		Map<String, String> payTypeMap = new HashMap<>();
		for (Dictionary payType : payTypeList) {
			payTypeMap.put(payType.getCode(), payType.getName());
		}
		Map<String, String> orderStatus = new HashMap<>();
		for (OrderStatus os : OrderStatus.values()) {
			orderStatus.put(os.getValue(), os.getName());
		}

		ZOSearchCondition sc = super.getSearchCondition();

		sc.put("orderStatus", "TS");//只需要导出成功的。
		String fileName = ZODate.getDateTime().replace(":", "-");
		String templatePath = SystemEnum.FilePath.ReportTemplate.getValue() + "admin_trade_details.xlsx";
		String targetPath = SystemEnum.FilePath.ReportTmp.getValue() + fileName + ".xlsx";
		LinkedHashMap<String, Context> sheetNameAndData = new LinkedHashMap<>();
		int loop = SystemEnum.BizType.values().length;
		String[] templateSheetName = new String[loop];
		for(int i = 0; i < loop; i++){
			int sheetIndex = i + 1;
			templateSheetName[i] = "Sheet" + sheetIndex;
		}
		//循环遍历交易类型
		for(SystemEnum.BizType type: SystemEnum.BizType.values()) {
			sc.put("bizType", type.getValue());//导出一种交易类型
			List<TradeOrder> items = TradeOrder.dao.searchReportForAdmin(sc);

			TradeOrder allOrder = new TradeOrder();//记录金额总和
			long allAmt = 0;
			long allFee = 0;
			for (TradeOrder item : items) {
				item.setOrderStatus(orderStatus.get(item.getOrderStatus()));
				allAmt += item.getAmount();
				allFee += item.getFee();
			}
			allOrder.setMerchCode("合计");
			allOrder.setMerchName("合计");
			allOrder.setAmount(allAmt);
			allOrder.setFee(allFee);
			items.add(allOrder);
			Context context = new Context();
			context.putVar("list", items);
			sheetNameAndData.put(type.getName(), context);
		}
		ZOExcel.exportLargeData(templatePath, targetPath, sheetNameAndData, templateSheetName);
		renderSuccess("/upload/report/tmp/" + fileName + ".xlsx");

	}


	public void reportSheet() throws Exception{
		String fileName = ZODate.getDateTime().replace(":", "-");
		String templatePath = SystemEnum.FilePath.ReportTemplate.getValue() + "sheet_trade_details.xlsx";
		String targetPath = SystemEnum.FilePath.ReportTmp.getValue() + fileName + ".xlsx";
		LinkedHashMap<String, Context> sheetNameAndData = new LinkedHashMap<>();
		int loop = 1;
		String[] templateSheetName = new String[loop];
		for(int i = 0; i < loop; i++){
			int sheetIndex = i + 1;
			templateSheetName[i] = "Sheet" + sheetIndex;
		}
		ZOSearchCondition sc = super.getSearchCondition();
		sc.put("orderStatus", "TS");//只需要导出成功的。

		List<TradeOrder> items = TradeOrder.dao.searchReportForAdminSheet(sc);
		Context context = new Context();
		context.putVar("list", items);
		sheetNameAndData.put("成功交易明细", context);

		ZOExcel.exportLargeData(templatePath, targetPath, sheetNameAndData, templateSheetName);
		renderSuccess("/upload/report/tmp/" + fileName + ".xlsx");
	}

	public void downBalance(){
		ReportService reportService = new ReportService();
		File file = null;
		List<String> filePath = new ArrayList<>();
		{
			file = reportService.virtualBalance(filePath, null);
		}
		if (filePath == null || filePath.isEmpty()) {
			renderFail("没有满足条件的数据");
		} else {
			renderSuccess("/upload/report/tmp/" +filePath.get(0));
		}
	}
}
